<section id = "doc_impl-spa" data-view = "true" data-view-title = "初步实现单页应用">
	<header>
		<a class = "nav-back" data-view-rel = ":back"></a>
		<span>初步实现单页应用</span>
		<a class = "menu"></a>
	</header>
	<div class = "body">
		<p>实现单页应用其实并不复杂。</p>
		<p>我们可以将多个不同的视图使用div等标签预先定义到html中，然后通过脚本动态控制特定视图的呈现与隐藏。例如：</p>
		<div class = "code html" >
&lt;div id = "view1" class = "view"&gt;page1&lt;/div&gt;
&lt;div id = "view2" class = "view"&gt;page2&lt;/div&gt;
		</div>
		<div class = "code js" >
/* 切换呈现的视图 */
document.querySelector(".view.active").classList.remove("active");
document.querySelector("#view2.view").classList.add("active");
		</div>
		<p>对于简单的场景，这种做法基本还能勉强应对。但面对更高的要求，如：“界面数据需要根据用户操作而动态变化”等时，逻辑就要再复杂一些。如果我们需要使用视图呈现商品详情并响应立即购买动作，那代码逻辑可能就要这么写：</p>
		<div class = "code html" >
&lt;div id = "goodsList" class = "view"&gt;Goods list&lt;/div&gt;
&lt;div id = "goodsDetail" class = "view"&gt;
	&lt;span class = "nav-back"&gt;&lt;/span&gt;
	&lt;div class = "name"&gt;商品名称&lt;/div&gt;
	&lt;div class = "detail"&gt;商品图文详情&lt;/div&gt;
	&lt;span class = "btn buy"&gt;立即购买&lt;/span&gt;
&lt;/div&gt;
		</div>
		<div class = "code js" >
var find = function(selector){
	return document.querySelector(selector);
};

/**
 * 呈现商品列表
 * @param {JsonObjectList} list 商品列表
 */
var showGoodsList = function(list){
	/* 切换呈现的视图 */
	find(".view.active").classList.remove("active");
	find("#goodsList").classList.add("active");
	
	list.forEach(function(goodsDetail){
		//TODO
	});
};

/**
 * 重置商品详情界面
 */
var resetGoodsDetail = function(){
	find("#goodsDetail").removeAttribute("data-goodsId");
	find(".name").innerHTML = "";
	find(".detail").innerHTML = "";
};

/**
 * 呈现商品详情
 * @param {JsonObject} goodsDetail 商品详情
 */
var showGoodsDetail = function(goodsDetail){
	/* 切换呈现的视图 */
	find(".view.active").classList.remove("active");
	find("#goodsDetail").classList.add("active");

	resetGoodsDetail();
	
	find("#goodsDetail").setAttribute("data-goodsId", goodsDetail.id);
	find("#goodsDetail .name").innerHTML = goodsDetail.name;
	find("#goodsDetail .detail").innerHTML = goodsDetail.detailHtml;
};

/* 立即购买 */
var buyObj = find("#goodsDetail .btn.buy");
Hammer(buyObj).on("tap", function(){
	var goodsId = find("#goodsDetail").getAttribute("data-goodsId");
	//TODO
});

/* 返回 */
var backObj = find("#goodsDetail .nav-back");
Hammer(backObj).on("tap", function(){
	var list;
	/* 获取商品列表 */
	//TODO
	
	showGoodsList(list);
});

document.addEventListener("DOMContentLoaded", function(){
	var goodsList;
	/* 获取商品列表 */
	//TODO
	
	showGoodsList(list);
	
	/* 返回 */
	var backObj = find("#goodsDetail .nav-back");
	Hammer(backObj).on("tap", function(){
		var list;
		/* 获取商品列表 */
		//TODO
		
		showGoodsList(list);
	});
});
		</div>
		<p>看上去确实没什么问题，应该可以正常工作。是的，确实是这样。但程序开发，并不青睐一个人单独作战，而是需要多人协作的。这个例子只证明了这种方案的可行性，但可行性与量产还不是同一个问题。如何以更优雅地方式在实现功能的前提下提升多人协作的便捷性，也是项目管理过程中的一个重要议题。</p>
		<p>就上面的例子而言，存在如下几个方面的问题：</p>
		<ol>
			<li>商品列表的逻辑与商品详情的逻辑无法清晰的剥离开来；</li>
			<li>视图之间的数据传递完全依赖带参数的渲染方法的主动调用；</li>
			<li>特定视图的数据暂存无法得到有效处理。如，渲染商品详情视图所需要的商品详情数据；</li>
			<li>特定视图打开后，无法借助URL传播。亦即用户A打开商品G的商品详情后，如果将URL发给B，B打开链接后看到的并不是商品G的商品详情，而是商品列表界面</li>
		</ol>
		<p>上面描述的种种问题，都需要一个业务无关的底层框架给予解决，使得应用开发者基本上只考虑各个视图的业务逻辑与视图之间的参数传递问题即可。</p>
	</div>
	<footer><div class = "btn next">下一节</div></footer>
</section>